from django.db import transaction
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from ERP_5.utils.get_inventory import get_inventory_by_goods
from warehouse_info.models import PurchaseStorageModel, PurchaseStorageItemModel

class StorageItemSerializer(serializers.ModelSerializer):
    """
    入库单的 项项目，序列化
    """
    # 注意：既然只有 库存数据没有，那么可以增加一个属性
    cur_inventory = serializers.SerializerMethodField(read_only=True, label='在当前仓库中库存')

    class Meta:
        model = PurchaseStorageItemModel
        fields = '__all__'

    def get_cur_inventory(self, obj):  # 当前的obj为：PurchaseStorageItemModel对象
        result = get_inventory_by_goods(obj.goods.id, obj.warehouse.id)
        return result if result else 0

class StorageSerializer(serializers.ModelSerializer):
    """
    入库单——反序列化器（用于新增和修改） 和 查询列表的序列化器
    """
    item_list = StorageItemSerializer(many=True)
    # 采购订单列表中需要展示：商品信息。
    goods_info = serializers.SerializerMethodField(read_only=True, label='列表中展示的商品信息')

    class Meta:
        model = PurchaseStorageModel
        fields = '__all__'

    def get_goods_info(self, obj):
        """
        商品信息是由： 商品1名称 商品1规格 , 商品2名称 商品2规格 ，....
        """
        if obj.item_list.all():
            result = []
            for item in obj.item_list.all():
                result.append(item.name + (item.specification if item.specification else ''))
            return ', '.join(result)
        return ""

    # 同时插入采购单和采购单中货品项。必须重写create
    def create(self, validated_data):
        item_list = validated_data.pop('item_list')
        with transaction.atomic():
            purchase_storage = PurchaseStorageModel.objects.create(**validated_data)
            for item in item_list:
                psi = PurchaseStorageItemModel.objects.create(purchase_storage=purchase_storage, **item)
                # 把一些冗余属性也加进去
                goods = item.get('goods')
                psi.specification = goods.specification
                psi.model_number = goods.model_number
                psi.number_code = goods.number_code
                psi.color = goods.color
                psi.category = goods.category
                psi.category_name = goods.category.name
                psi.units = goods.units
                psi.units_name = goods.units.basic_name
                psi.save()
        return purchase_storage

    # 同时插入采购单和采购单中货品项。必须重写update
    def update(self, instance, validated_data):
        if instance.status == '1':
            raise ValidationError("入库单已经生效，不能修改")
        item_list = validated_data.pop('item_list')
        old_list = instance.item_list.all()
        with transaction.atomic():
            if old_list.exists():
                # 然后把旧数据删除，因为在validated_data拿不到货品库存数据的ID
                instance.item_list.all().delete()

            for item in item_list:  # 重新插入采购项 数据
                psi = PurchaseStorageItemModel.objects.create(purchase_storage=instance, **item)
                # 把一些冗余属性也加进去
                goods = item.get('goods')
                psi.specification = goods.specification
                psi.model_number = goods.model_number
                psi.number_code = goods.number_code
                psi.color = goods.color
                psi.category = goods.category
                psi.category_name = goods.category.name
                psi.units = goods.units
                psi.units_name = goods.units.basic_name
                psi.save()
            result = super(StorageSerializer, self).update(instance=instance, validated_data=validated_data)
        return result